home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / nroff / text.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  12KB  |  784 lines

  1. /*
  2.  *    text.c - text output processing portion of nroff word processor
  3.  *
  4.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  5.  *    net:    rosenkra@hall.cray.com
  6.  *    CIS:    71460,17
  7.  *    GENIE:    W.ROSENKRANZ
  8.  *
  9.  *    original author:
  10.  *
  11.  *    Stephen L. Browning
  12.  *    5723 North Parker Avenue
  13.  *    Indianapolis, Indiana 46220
  14.  *
  15.  *    history:
  16.  *
  17.  *    - Originally written in BDS C;
  18.  *    - Adapted for standard C by W. N. Paul
  19.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  20.  *    - Adapted the justification of lines with escape codes 
  21.  *      by Wim 'Blue Baron' van Dorst (wsincc@tuerc3.urc.tue.nl)
  22.  */
  23.  
  24. #undef NRO_MAIN                    /* extern globals */
  25.  
  26. #include <stdio.h>
  27. #include "nroff.h"
  28.  
  29.  
  30. /*------------------------------*/
  31. /*    text            */
  32. /*------------------------------*/
  33. text (p)
  34. register char  *p;
  35. {
  36.  
  37. /*
  38.  *    main text processing
  39.  */
  40.  
  41.     register int    i;
  42.     char        wrdbuf[MAXLINE];
  43.  
  44.  
  45.     /*
  46.      *   skip over leading blanks if in fill mode. we indent later.
  47.      *   since leadbl does a robrk, do it if in .nf mode
  48.      */
  49.     if (dc.fill == YES)
  50.     {
  51.         if (*p == ' ' || *p == '\n' || *p == '\r')
  52.             leadbl (p);
  53.     }
  54.     else
  55.         robrk ();
  56.  
  57.  
  58.     /*
  59.      *   expand escape sequences
  60.      */
  61.     expesc (p, wrdbuf);
  62.  
  63.  
  64.     /*
  65.      *   test for how to output
  66.      */
  67.     if (dc.ulval > 0)
  68.     {
  69.         /*
  70.          *   underline (.ul)
  71.          *
  72.          *   Because of the way underlining is handled,
  73.          *   MAXLINE should be declared to be three times
  74.          *   larger than the longest expected input line
  75.          *   for underlining.  Since many of the character
  76.          *   buffers use this parameter, a lot of memory
  77.          *   can be allocated when it may not really be
  78.          *   needed.  A MAXLINE of 180 would allow about
  79.          *   60 characters in the output line to be
  80.          *   underlined (remember that only alphanumerics
  81.          *   get underlined - no spaces or punctuation).
  82.          */
  83.         underl (p, wrdbuf, MAXLINE);
  84.         --dc.ulval;
  85.     }
  86.     if (dc.cuval > 0)
  87.     {
  88.         /*
  89.          *   continuous underline (.cu)
  90.          */
  91.         underl (p, wrdbuf, MAXLINE);
  92.         --dc.cuval;
  93.     }
  94.     if (dc.boval > 0)
  95.     {
  96.         /*
  97.          *   bold (.bo)
  98.          */
  99.         bold (p, wrdbuf, MAXLINE);
  100.         --dc.boval;
  101.     }
  102.     if (dc.ceval > 0)
  103.     {
  104.         /*
  105.          *   centered (.ce)
  106.          */
  107.         center (p);
  108.         put (p);
  109.         --dc.ceval;
  110.     }
  111.     else if ((*p == '\r' || *p == '\n') && dc.fill == NO)
  112.     {
  113.         /*
  114.          *   all blank line
  115.          */
  116.         put (p);
  117.     }
  118.     else if (dc.fill == NO)
  119.     {
  120.         /*
  121.          *   unfilled (.nf)
  122.          */
  123.         put (p);
  124.     }
  125.     else
  126.     {
  127.         /*
  128.          *   anything else...
  129.          */
  130.  
  131.         /*
  132.          *   get a word and put it out. increment ptr to the next
  133.          *   word.
  134.          */
  135.         while ((i = getwrd (p, wrdbuf)) > 0)
  136.         {
  137.             putwrd (wrdbuf);
  138.             p += i;
  139.         }
  140.     }
  141. }
  142.  
  143.  
  144.  
  145.  
  146. /*------------------------------*/
  147. /*    bold            */
  148. /*------------------------------*/
  149. bold (p0, p1, size)
  150. register char  *p0;
  151. register char  *p1;
  152. int        size;
  153. {
  154.  
  155. /*
  156.  *    insert bold face text (by overstriking)
  157.  */
  158.  
  159.     register int    i;
  160.     register int    j;
  161.  
  162.     j = 0;
  163.     for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
  164.     {
  165.         if (isalpha (p0[i]) || isdigit (p0[i]))
  166.         {
  167.             p1[j++] = p0[i];
  168.             p1[j++] = '\b';
  169.         }
  170.         p1[j++] = p0[i];
  171.     }
  172.     p1[j++] = '\n';
  173.     p1[j] = EOS;
  174.     while (*p1 != EOS)
  175.         *p0++ = *p1++;
  176.     *p0 = EOS;
  177. }
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /*------------------------------*/
  185. /*    center            */
  186. /*------------------------------*/
  187. center (p)
  188. register char  *p;
  189. {
  190.  
  191. /*
  192.  *    center a line by setting tival
  193.  */
  194.  
  195.     dc.tival = max ((dc.rmval + dc.tival - width (p)) >> 1, 0);
  196. }
  197.  
  198.  
  199.  
  200.  
  201. /*------------------------------*/
  202. /*    expand            */
  203. /*------------------------------*/
  204. expand (p0, c, s)
  205. register char  *p0;
  206. char        c;
  207. register char  *s;
  208. {
  209.  
  210. /*
  211.  *    expand title buffer to include character string
  212.  */
  213.  
  214.     register char  *p;
  215.     register char  *q;
  216.     register char  *r;
  217.     char        tmp[MAXLINE];
  218.  
  219.     p = p0;
  220.     q = tmp;
  221.     while (*p != EOS)
  222.     {
  223.         if (*p == c)
  224.         {
  225.             r = s;
  226.             while (*r != EOS)
  227.                 *q++ = *r++;
  228.         }
  229.         else
  230.             *q++ = *p;
  231.         ++p;
  232.     }
  233.     *q = EOS;
  234.     strcpy (p0, tmp);        /* copy it back */
  235. }
  236.  
  237.  
  238.  
  239.  
  240. /*------------------------------*/
  241. /*    justcntr        */
  242. /*------------------------------*/
  243. justcntr (p, q, limit)
  244. register char  *p;
  245. char           *q;
  246. int           *limit;
  247. {
  248.  
  249. /*
  250.  *    center title text into print buffer
  251.  */
  252.  
  253.     register int    len;
  254.  
  255.     len = width (p);
  256.     q   = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
  257.     while (*p != EOS)
  258.         *q++ = *p++;
  259. }
  260.  
  261.  
  262.  
  263.  
  264.  
  265. /*------------------------------*/
  266. /*    justleft        */
  267. /*------------------------------*/
  268. justleft (p, q, limit)
  269. register char  *p;
  270. char           *q;
  271. int        limit;
  272. {
  273.  
  274. /*
  275.  *    left justify title text into print buffer
  276.  */
  277.  
  278.     q = &q[limit];
  279.     while (*p != EOS)
  280.         *q++ = *p++;
  281. }
  282.  
  283.  
  284.  
  285.  
  286. /*------------------------------*/
  287. /*    justrite        */
  288. /*------------------------------*/
  289. justrite (p, q, limit)
  290. register char  *p;
  291. char           *q;
  292. int         limit;
  293. {
  294.  
  295. /*
  296.  *    right justify title text into print buffer
  297.  */
  298.  
  299.     register int    len;
  300.  
  301.     len = width (p);
  302.     q = &q[limit - len];
  303.     while (*p != EOS)
  304.         *q++ = *p++;
  305. }
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312. /*------------------------------*/
  313. /*    leadbl            */
  314. /*------------------------------*/
  315. leadbl (p)
  316. register char  *p;
  317. {
  318.  
  319. /*
  320.  *    delete leading blanks, set tival
  321.  */
  322.  
  323.     register int    i;
  324.     register int    j;
  325.  
  326.     /*
  327.      *   end current line and reset co struct
  328.      */
  329.     robrk ();
  330.  
  331.     /*
  332.      *   skip spaces
  333.      */
  334.     for (i = 0; p[i] == ' ' || p[i] == '\t'; ++i)
  335.         ;
  336.  
  337.     /*
  338.      *   if not end of line, reset current temp indent
  339.      */
  340. #ifdef GEMDOS
  341.     if (p[i] != '\n' && p[i] != '\r')
  342.         dc.tival = i;
  343. #else
  344.     if (p[i] != '\n' && p[i] != '\r')
  345.         dc.tival = i;
  346. #endif
  347.  
  348.     /*
  349.      *   shift string
  350.      */
  351.     for (j = 0; p[i] != EOS; ++j)
  352.         p[j] = p[i++];
  353.     p[j] = EOS;
  354. }
  355.  
  356.  
  357.  
  358.  
  359.  
  360. /*------------------------------*/
  361. /*    pfoot            */
  362. /*------------------------------*/
  363. pfoot ()
  364. {
  365.  
  366. /*
  367.  *    put out page footer
  368.  */
  369.  
  370.     if (dc.prflg == TRUE)
  371.     {
  372.         skip (pg.m3val);
  373.         if (pg.m4val > 0)
  374.         {
  375.             if ((pg.curpag % 2) == 0)
  376.             {
  377.                 puttl (pg.efoot, pg.eflim, pg.curpag);
  378.             }
  379.             else
  380.             {
  381.                 puttl (pg.ofoot, pg.oflim, pg.curpag);
  382.             }
  383.             skip (pg.m4val - 1);
  384.         }
  385.     }
  386. }
  387.  
  388.  
  389.  
  390.  
  391.  
  392. /*------------------------------*/
  393. /*    phead            */
  394. /*------------------------------*/
  395. phead ()
  396. {
  397.  
  398. /*
  399.  *    put out page header
  400.  */
  401.  
  402.     pg.curpag = pg.newpag;
  403.     if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg)
  404.     {
  405.         dc.prflg = TRUE;
  406.     }
  407.     else
  408.     {
  409.         dc.prflg = FALSE;
  410.     }
  411.     ++pg.newpag;
  412.     set_ireg ("%", pg.newpag, 0);
  413.     if (dc.prflg == TRUE)
  414.     {
  415.         if (pg.m1val > 0)
  416.         {
  417.             skip (pg.m1val - 1);
  418.             if ((pg.curpag % 2) == 0)
  419.             {
  420.                 puttl (pg.ehead, pg.ehlim, pg.curpag);
  421.             }
  422.             else
  423.             {
  424.                 puttl (pg.ohead, pg.ohlim, pg.curpag);
  425.             }
  426.         }
  427.         skip (pg.m2val);
  428.     }
  429.     /* 
  430.      *    initialize lineno for the next page
  431.      */
  432.     pg.lineno = pg.m1val + pg.m2val + 1;
  433.     set_ireg ("ln", pg.lineno, 0);
  434. }
  435.  
  436.  
  437.  
  438.  
  439. /*------------------------------*/
  440. /*    puttl            */
  441. /*------------------------------*/
  442. puttl (p, lim, pgno)
  443. register char  *p;
  444. int           *lim;
  445. int        pgno;
  446. {
  447.  
  448. /*
  449.  *    put out title or footer
  450.  */
  451.  
  452.     register int    i;
  453.     char        pn[8];
  454.     char        t[MAXLINE];
  455.     char        h[MAXLINE];
  456.     char        delim;
  457.  
  458.     itoda (pgno, pn, 6);
  459.     for (i = 0; i < MAXLINE; ++i)
  460.         h[i] = ' ';
  461.     delim = *p++;
  462.     p = getfield (p, t, delim);
  463.     expand (t, dc.pgchr, pn);
  464.     justleft (t, h, lim[LEFT]);
  465.     p = getfield (p, t, delim);
  466.     expand (t, dc.pgchr, pn);
  467.     justcntr (t, h, lim);
  468.     p = getfield (p, t, delim);
  469.     expand (t, dc.pgchr, pn);
  470.     justrite (t, h, lim[RIGHT]);
  471.     for (i = MAXLINE - 4; h[i] == ' '; --i)
  472.         h[i] = EOS;
  473.     h[++i] = '\n';
  474. #ifdef GEMDOS
  475.     h[++i] = '\r';
  476. #endif
  477.     h[++i] = EOS;
  478.     if (strlen (h) > 2)
  479.     {
  480.         for (i = 0; i < pg.offset; ++i)
  481.             prchar (' ', out_stream);
  482.     }
  483.     putlin (h, out_stream);
  484. }
  485.  
  486.  
  487.  
  488.  
  489.  
  490. /*------------------------------*/
  491. /*    putwrd            */
  492. /*------------------------------*/
  493. putwrd (wrdbuf)
  494. register char  *wrdbuf;
  495. {
  496.  
  497. /*
  498.  *    put word in output buffer
  499.  */
  500.  
  501.     register char  *p0;
  502.     register char  *p1;
  503.     int         w;
  504.     int         last;
  505.     int         llval;
  506.     int         nextra;
  507.  
  508.  
  509.  
  510.     /*
  511.      *   check if this word puts us over the limit
  512.      */
  513.     w     = width (wrdbuf);
  514.     last  = strlen (wrdbuf) + co.outp;
  515.     llval = dc.rmval - dc.tival;
  516.     co.outesc += countesc (wrdbuf);
  517.     if (((co.outp > 0) && ((co.outw + w - co.outesc) > llval))
  518.     ||   (last > MAXLINE))
  519.     {
  520.         /*
  521.          *   last word exceeds limit so prepare to break line, print
  522.          *   it, and reset outbuf.
  523.          */
  524.         last -= co.outp;
  525.         if (dc.juval == YES)
  526.         {
  527.             nextra = llval - co.outw + 1;
  528.  
  529.             /*
  530.              *    Do not take in the escape char of the
  531.              *     word that didn't fit on this line anymore
  532.              */
  533.              co.outesc -= countesc (wrdbuf);
  534.             
  535.             /* 
  536.              *    Check whether last word was end of
  537.              *    sentence and modify counts so that
  538.              *    it is right j